/**
 * @file hcc_error_code.h
 * @brief  
 * @note 
 * @author
 * @date 
 * @version 1.0

 一. 错误码编码规范:
    bit31                               bit0
    v                                   v  
    1 1111111111 11 1111111 11111111 1111
    A B          C  D       E        F
    A: 1bit, 固定为1,即表示负数
    B: 10bit, 返回错误时的行号
    C: 2bit, 模块分类
        0: 驱动模块
        1: 中间件
        2: 第三方模块返回的错误码
        3: 业务类应用
    D: 7bit, 错误码
    E: 8bit, 模块编号,统一定义
    F: 4bit, 错误级别,值越大越严重

 二. 定义错误码的示例: 定义CAN驱动的错误码
    #include <hcc_error_code.h>
    #include <hcc_error_code_mod.h>
    #define HCC_MAKE_DRV_CAN_ERROR(error_code) HCC_MAKE_DRIVER_ERROR(kHccDrvCan, error_code, HCC_ERROR_LEVEL_ERROR)

    typedef enum TDrvCan_TErrorCodeTag TDrvCan_TErrorCode; 
    enum TDrvCan_TErrorCodeTag
    {
        kDrvCanErrorSuccess = HCC_ERROR_SUCCESS,  ///< 成功,没有错误
        kDrvCanErrorOpen = HCC_MAKE_DRV_CAN_ERROR(0),  ///< 打开驱动失败
        kDrvCanErrorInvalidParam = HCC_MAKE_DRV_CAN_ERROR(1),  ///< 无效的参数
    };

 * @par          修改日志
 * <table>
 * <tr><th>Date<th>Version<th>Author<th>Description
 * <tr><td>2020-9-10<td>1.0<td>Leo<td>创建初始版本
 * @copyright 杭州鸿泉物联网技术股份有限公司
 */

#ifndef _HCC_ERROR_CODE_H_
#define _HCC_ERROR_CODE_H_

#ifdef __cplusplus
extern "C" {
#endif

/// 成功时的错误码定义,即没有错误
#define HCC_ERROR_SUCCESS 0

/// 统一的输出错误码定义; 小于0(HCC_ERROR_SUCCESS)为错误,其它为成功
typedef unsigned int THccErrorCode;

/// 错误级别相关的宏
#define HCC_ERROR_LEVEL_SHIFT 0
#define HCC_ERROR_LEVEL_BITS 4
#define HCC_ERROR_LEVEL_MASK (((1u << HCC_ERROR_LEVEL_BITS) - 1) << HCC_ERROR_LEVEL_SHIFT)
#define HCC_MAKE_ERROR_LEVEL(error_level) (((error_level) << HCC_ERROR_LEVEL_SHIFT) & HCC_ERROR_LEVEL_MASK)
#define HCC_GET_ERROR_LEVEL(code) (((code) & HCC_ERROR_LEVEL_MASK) >> HCC_ERROR_LEVEL_SHIFT)

/// 模块编号相关的宏
#define HCC_MODULE_NO_SHIFT (HCC_ERROR_LEVEL_SHIFT + HCC_ERROR_LEVEL_BITS)
#define HCC_MODULE_NO_BITS 8
#define HCC_MODULE_NO_MASK (((1u << HCC_MODULE_NO_BITS) - 1) << HCC_MODULE_NO_SHIFT)
#define HCC_MAKE_MODULE_NO(module_no) (((module_no) << HCC_MODULE_NO_SHIFT) & HCC_MODULE_NO_MASK)
#define HCC_GET_MODULE_NO(code) (((code) & HCC_MODULE_NO_MASK) >> HCC_MODULE_NO_SHIFT)

/// 错误码相关的宏
#define HCC_ERROR_CODE_SHIFT (HCC_MODULE_NO_SHIFT + HCC_MODULE_NO_BITS)
#define HCC_ERROR_CODE_BITS 7
#define HCC_ERROR_CODE_MASK (((1u << HCC_ERROR_CODE_BITS) - 1) << HCC_ERROR_CODE_SHIFT)
#define HCC_MAKE_ERROR_CODE(error_code) (((error_code) << HCC_ERROR_CODE_SHIFT) & HCC_ERROR_CODE_MASK)
#define HCC_GET_ERROR_CODE(code) (((code) & HCC_ERROR_CODE_MASK) >> HCC_ERROR_CODE_SHIFT)

/// 模块类型相关的宏
#define HCC_MODULE_TYPE_SHIFT (HCC_ERROR_CODE_SHIFT + HCC_ERROR_CODE_BITS)
#define HCC_MODULE_TYPE_BITS 2
#define HCC_MODULE_TYPE_MASK (((1u << HCC_MODULE_TYPE_BITS) - 1) << HCC_MODULE_TYPE_SHIFT)
#define HCC_MAKE_MODULE_TYPE(module_type) (((module_type) << HCC_MODULE_TYPE_SHIFT) & HCC_MODULE_TYPE_MASK)
#define HCC_GET_MODULE_TYPE(code) (((code) & HCC_MODULE_TYPE_MASK) >> HCC_MODULE_TYPE_SHIFT)

/// 错误所在的行相关的宏
#define HCC_ERROR_LINE_SHIFT (HCC_MODULE_TYPE_SHIFT + HCC_MODULE_TYPE_BITS)
#define HCC_ERROR_LINE_BITS 10
#define HCC_ERROR_LINE_MASK (((1u << HCC_ERROR_LINE_BITS) - 1) << HCC_ERROR_LINE_SHIFT)
#define HCC_MAKE_ERROR_LINE(error_line) ((((unsigned int)error_line) << HCC_ERROR_LINE_SHIFT) & HCC_ERROR_LINE_MASK)
#define HCC_GET_ERROR_LINE(code) (((code) & HCC_ERROR_LINE_MASK) >> HCC_ERROR_LINE_SHIFT)

/// 模块类型
#define HCC_MODULE_TYPE_DRIVER 0u  ///< 驱动模块
#define HCC_MODULE_TYPE_MID_WARE 1u  ///< 中间件
#define HCC_MODULE_TYPE_THIRD_MD 2u  ///< 第三方模块
#define HCC_MODULE_TYPE_APP 3u  ///< 应用模块

/// 错误级别
#define HCC_ERROR_LEVEL_CRITICAL 15u  ///< 致命级别
#define HCC_ERROR_LEVEL_SERIOUS 12u  ///< 严重错误级别
#define HCC_ERROR_LEVEL_ERROR 8u  ///< 错误级别
#define HCC_ERROR_LEVEL_WARNING 4u  ///< 警告级别
#define HCC_ERROR_LEVEL_HINT 0u  ///< 提示级别

/**
 * 生成错误码
 * @param module_type: 模块类型
 * @param module_no: 模块编号
 * @param error_code: 错误码
 * @param error_level: 错误等级;值越大,错误等级越高
 * @return 
 */
#define HCC_MAKE_ERROR(module_type, module_no, error_code, error_level) \
    (THccErrorCode)(0x80000000 | (HCC_MAKE_MODULE_TYPE(module_type)) | (HCC_MAKE_MODULE_NO(module_no)) \
    | (HCC_MAKE_ERROR_CODE(error_code)) | (HCC_MAKE_ERROR_LEVEL(error_level)))

/**
 * 生成驱动类型的错误码
 * @param module_no: 模块编号
 * @param error_code: 错误码
 * @param error_level: 错误等级;值越大,错误等级越高
 * @return 
 */
#define HCC_MAKE_DRIVER_ERROR(module_no, error_code, error_level) HCC_MAKE_ERROR(HCC_MODULE_TYPE_DRIVER, module_no, error_code, error_level)

/**
 * 生成中间件类型的错误码
 * @param module_no: 模块编号
 * @param error_code: 错误码
 * @param error_level: 错误等级;值越大,错误等级越高
 * @return 
 */
#define HCC_MAKE_MID_WARE_ERROR(module_no, error_code, error_level) HCC_MAKE_ERROR(HCC_MODULE_TYPE_MID_WARE, module_no, error_code, error_level)

/**
 * 生成第三方模块返回的错误码
 * @param module_no: 模块编号
 * @param error_code: 错误码
 * @param error_level: 错误等级;值越大,错误等级越高
 * @return 
 */
#define HCC_MAKE_THIRD_MD_ERROR(module_no, error_code, error_level) HCC_MAKE_ERROR(HCC_MODULE_TYPE_THIRD_MD, module_no, error_code, error_level)

/**
 * 生成应用层的错误码
 * @param module_no: 模块编号
 * @param error_code: 错误码
 * @param error_level: 错误等级;值越大,错误等级越高
 * @return 
 */
#define HCC_MAKE_APP_ERROR(module_no, error_code, error_level) HCC_MAKE_ERROR(HCC_MODULE_TYPE_APP, module_no, error_code, error_level)

/**
 * 返回错误码,并指定错误码所在的行号
 * 使用方法: return HCC_ERROR(kDrvCanErrorOpen)
 * @param code: 错误码信息
 * @return 
 */
#define HCC_ERROR(code) (((int)code) >= 0 ? (code) : ((code) | (HCC_MAKE_ERROR_LINE(__LINE__))))

/**
 * 返回错误码去掉行号后的值
 * @param code: 包含行号的错误码
 * @return 
 */
#define HCC_ERROR_CODE(code) (THccErrorCode)(((unsigned int)code) & (0x80000000u | HCC_ERROR_LEVEL_MASK | HCC_ERROR_CODE_MASK | HCC_MODULE_NO_MASK | HCC_MODULE_TYPE_MASK))

#ifdef __cplusplus
}  // extern "C"
#endif

#endif // _HCC_ERROR_CODE_H_
/**
 * @} 
 */


